/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.elem.uml;

import java.awt.Rectangle;
import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import self.amigo.elem.ARectangularHandledElement;
import self.amigo.elem.ARectangularLinkable;
import self.awt.PainterManager;
import self.gee.IDiagramLayer;
import self.gee.IGraphicElement;
import self.lang.StringUtils;
import self.xml.DomUtils;


public class NameAndCompositionCompartmentsView extends ARectangularLinkable {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
  final static public String NAMECOMPARTMENT_PROP = "NameCompartment";
  final static public String COMPOSITIONCOMPARTMENT_PROP = "Composition";
    
  public NameAndCompositionCompartmentsView() {
    delegate = createDelegate();
    setDelegate( delegate );
  }

  protected IGraphicElement createDelegate() {
    throw new UnsupportedOperationException( "Templates are expected to override the factory method" );
  }
  
  abstract protected class AEssential extends ARectangularHandledElement {
    transient protected ICompartmentsRenderInfo     context = new PaintContext();
    protected NameCompartmentFeature      nameCompartment = new NameCompartmentFeature();
    private AuxilaryCompartmentFeature  composition = new AuxilaryCompartmentFeature();
    protected Rectangle figCompartment = new Rectangle();
    protected MultiCompartmentPainter   compartmentPainter; 

    private String[]                    compDetails = new String[1];
    private boolean[]                   compDetailsVis = new boolean[1];

    public AEssential() {
      fig.setBounds( 10, 10, 110, 80 );
      resetFrame();
    }
    
    protected boolean isNamedUnderlined() {
      return false;
    }
    
    public void       setLayer( IDiagramLayer layerToDrawOn, boolean add ) {
      super.setLayer( layerToDrawOn, add );
      compartmentPainter = (MultiCompartmentPainter) PainterManager.getPainterForOwner( 
                                          layer, MultiCompartmentPainter.class );
    }

    // IEditableElement support
    public void       getProperties( Map store ) {
      store.put( NAMECOMPARTMENT_PROP, nameCompartment.clone() );
      store.put( COMPOSITIONCOMPARTMENT_PROP, composition.clone() );
    }
    
    public void       setProperties( Map data ) {
      nameCompartment.set( (NameCompartmentFeature)data.get( NAMECOMPARTMENT_PROP) );
      composition.set( (AuxilaryCompartmentFeature)data.get( COMPOSITIONCOMPARTMENT_PROP) );
      layer.setDirty();
    }
    
    // IPersistentElement support
    public void readFrom( Node self, HashMap idObjLookUp ) throws DOMException {
      super.readFrom( self, idObjLookUp );
      nameCompartment.readFrom( self, idObjLookUp );
      
      Node comp = DomUtils.getChildElementNode( self, COMPOSITIONCOMPARTMENT_PROP );
      composition.readFrom( comp, idObjLookUp );
    }
  
    public void writeTo( Document doc, Element self, HashMap objIdLookup ) throws DOMException {
      super.writeTo( doc, self, objIdLookup );
      nameCompartment.writeTo( doc, self, objIdLookup );

      Element comp = doc.createElement( COMPOSITIONCOMPARTMENT_PROP );
      self.appendChild( comp );
      composition.writeTo( doc, comp, objIdLookup );
    }
    
    class PaintContext implements ICompartmentsRenderInfo {
      public Rectangle  getBounds() {
        return figCompartment;
      }
      
      public String     getName() {
        return nameCompartment.name;
      }
      
      public String     getSymbol() {
        return StringUtils.toNullOrNonEmptyValue( nameCompartment.aidLink );
      }

      public boolean    isNameUnderlined() {
        return AEssential.this.isNamedUnderlined();
      }
      
      public boolean    isNameItalic() {
        return false;
      }
      
      public String     getStereoType() {
        return StringUtils.toNullOrNonEmptyValue( nameCompartment.stereotype );
      }
      
      public String     getNamespace() {
        return StringUtils.toNullOrNonEmptyValue( nameCompartment.nameSpace );
      }
      
      public boolean[] getVisibleAuxilaryCompartments() {
        compDetailsVis[0] = composition.visible;
        return compDetailsVis;
      }
      
      public String[]  getAuxilaryCompartments() {
        compDetails[0] = composition.details;
        return compDetails;
      }
    }
  }  
}
